package at.ac.tuwien.ame;

import at.ac.tuwien.ame.EcoreModelProjectPredicate;
import at.ac.tuwien.ame.FTLCodeGenerator;
import at.ac.tuwien.ame.FTLCompiler;
import at.ac.tuwien.ame.FTLUtils;
import com.google.common.collect.Iterables;
import ftldsl.ModelElement;
import ftldsl.Transformation;
import java.util.Collection;
import javax.inject.Inject;
import org.eclipse.core.internal.resources.File;
import org.eclipse.core.internal.resources.Folder;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.codegen.util.ImportManager;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;

@SuppressWarnings("all")
public class FTLGenerator implements IGenerator {
  @Inject
  private ImportManager importManager;
  
  @Inject
  private FTLCodeGenerator codeGenerator;
  
  public String str(final Transformation t) {
    ModelElement _context = t.getContext();
    String _name = _context.getName();
    String _unqualifiedName = FTLUtils.getUnqualifiedName(_name);
    String _plus = (_unqualifiedName + "Transformation");
    return _plus;
  }
  
  /**
   * Performs a lookup of the metamodel to use located within the workspace and loads it.
   */
  public void loadMetaModel(final Resource input) {
    try {
      final IWorkspace workspace = ResourcesPlugin.getWorkspace();
      final IWorkspaceRoot root = workspace.getRoot();
      IProject[] _projects = root.getProjects();
      EcoreModelProjectPredicate _ecoreModelProjectPredicate = new EcoreModelProjectPredicate();
      Iterable<IProject> _filter = Iterables.<IProject>filter(((Iterable<IProject>)Conversions.doWrapArray(_projects)), _ecoreModelProjectPredicate);
      for (final IProject p : _filter) {
        {
          IFolder _folder = p.getFolder("model");
          final Folder folder = ((Folder) _folder);
          IResource[] _members = folder.members();
          for (final IResource r : _members) {
            String _name = r.getName();
            boolean _endsWith = _name.endsWith(".ecore");
            if (_endsWith) {
              IPath _fullPath = ((File) r).getFullPath();
              final java.io.File path = _fullPath.toFile();
              ResourceSet _resourceSet = input.getResourceSet();
              String _path = path.getPath();
              URI _createPlatformResourceURI = URI.createPlatformResourceURI(_path, true);
              Resource _resource = _resourceSet.getResource(_createPlatformResourceURI, true);
              FTLCompiler.resource = _resource;
              String _name_1 = r.getName();
              String _name_2 = r.getName();
              int _lastIndexOf = _name_2.lastIndexOf("/");
              int _plus = (_lastIndexOf + 1);
              String _name_3 = r.getName();
              int _lastIndexOf_1 = _name_3.lastIndexOf(".");
              String _substring = _name_1.substring(_plus, _lastIndexOf_1);
              this.codeGenerator.modelName = _substring;
              return;
            }
          }
        }
      }
    } catch (Exception _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  /**
   * Uses an {@link FTLCodeGenerator} to compile FTL {@link Transformation}s to the desired target language.
   */
  public void doGenerate(final Resource input, final IFileSystemAccess fsa) {
    this.loadMetaModel(input);
    Collection<String> _imports = this.importManager.getImports();
    _imports.clear();
    this.importManager.addImport("java.util.*");
    this.importManager.addImport("java.lang.reflect.*");
    this.importManager.addImport("org.eclipse.emf.common.util.*");
    this.importManager.addImport("org.eclipse.emf.ecore.*");
    this.importManager.addImport("org.eclipse.emf.ecore.resource.*");
    this.importManager.addImport("org.eclipse.emf.ecore.resource.impl.*");
    this.importManager.addImport("org.eclipse.emf.ecore.xmi.impl.*");
    EList<EObject> _contents = input.getContents();
    Iterable<Transformation> _filter = Iterables.<Transformation>filter(_contents, Transformation.class);
    for (final Transformation t : _filter) {
      {
        ModelElement _context = t.getContext();
        String _name = _context.getName();
        String _package = FTLUtils.getPackage(_name);
        String _replace = _package.replace(".", "/");
        String _str = this.str(t);
        final String fileName = String.format("%s/%s.java", _replace, _str);
        CharSequence _generateTransformation = this.codeGenerator.generateTransformation(t);
        fsa.generateFile(fileName, _generateTransformation);
      }
    }
    Collection<String> _imports_1 = this.importManager.getImports();
    _imports_1.clear();
  }
}
